/*
 * @Author jiangzhiwei
 * @Date 2023-07-21 11:30:58
 * @LastEditors jiangzhiwei
 * @LastEditTime 2023-07-28 11:28:20
 * @FilePath \test-cron\src\components\yc-cron\components\base\common-input-number\index.js
 * @Description 计数器组件
 */
import { defineComponent } from 'vue-demi'
import { h } from '../../../utils/domutil'
import { emitValue } from '../../../utils/componentutil'
import { VALUE_NAME } from '../../../utils/constant'
import './inputnumber.css'

/** 不允许空格的数字正则 */
const numRegexp = /^(\+|-)?\d*(\.\d*)?$/
const NAME = 'yc-cron-input-number'
const ICON_NAME = 'yc-cron-icon'

export default defineComponent({
  name: NAME,
  props: {
    [VALUE_NAME]: {
      type: Number,
      default: 0
    },
    min: {
      type: Number,
      default: undefined
    },
    max: {
      type: Number,
      default: undefined
    },
    step: {
      type: Number,
      default: 1
    },
    size: {
      type: String,
      default: undefined
    },
    disabled: {
      type: Boolean,
      default: false
    },
    controls: {
      type: Boolean,
      default: true
    },
    controlsPosition: {
      type: String,
      default: undefined
    },
    name: {
      type: String,
      default: undefined
    },
    placeholder: {
      type: String,
      default: undefined
    },
    /** 数字与字符串的映射 */
    valueMap: {
      type: Object,
      default: undefined
    }
  },
  data () {
    return {
      oldValue: 0,
      /** 是否获得焦点 */
      isFocus: false
    }
  },
  computed: {
    /** 根据valueMap显示的文本 */
    label () {
      return this.valueMap && this.valueMap[this[VALUE_NAME]]
    }
  },
  watch: {
    [VALUE_NAME] (value) {
      this.validateValue(value)
    },
    oldValue (value) {
      emitValue(this, value)
    }
  },
  mounted () {
    this.validateValue()
  },
  methods: {
    /** 获得焦点 */
    onFocus () {
      this.isFocus = true
    },
    /** 失去焦点校验 */
    onBlur () {
      this.isFocus = false
      this.validateValue()
    },
    /** 阻止input进行emit */
    onInput (e) {
      e.stopPropagation()
    },
    /** 按下上下键加减数字 */
    onKeydown (e) {
      if (e.code === 'ArrowUp') {
        e.preventDefault()
        this.plus()
      } else if (e.code === 'ArrowDown') {
        e.preventDefault()
        this.minus()
      }
    },
    /** 回车键松开时校验 */
    onKeyup (e) {
      if (e.code === 'Enter') {
        this.validateValue()
      }
    },
    /**
     * @Author jiangzhiwei
     * @Date 2023-07-21 17:13:58
     * @Description 校验值是否是数字
     * @param {number | undefined} value
     * @return {undefined}
     */
    validateValue (value) {
      value = typeof value === 'number' ? value : this.$refs.input.value
      if (value && numRegexp.test(value)) { // 如果是数字
        let oldValue = Number.parseFloat(value)
        this.oldValue = this.getHandlerValue(oldValue)
      }
      this.$refs.input.value = this.oldValue
    },
    /** 处理设置了min/max的数据 */
    getHandlerValue (value) {
      if (this.min !== undefined && value < this.min) {
        value = this.min
      } else if (this.max !== undefined && value > this.max) {
        value = this.max
      }
      return value
    },
    plus () {
      this.oldValue = this.getHandlerValue(this.oldValue + this.step)
    },
    minus () {
      this.oldValue = this.getHandlerValue(this.oldValue - this.step)
    }
  },
  render () {
    return h(
      'article',
      {
        class: {
          [NAME]: true,
          'is-disabled': this.disabled,
          'is-controls-right': this.controls && this.controlsPosition === 'right',
          [`${NAME}--${this.size}`]: this.size
        }
      },
      [
        h(
          'input',
          {
            class: `${NAME}__input`,
            ref: 'input',
            attrs: { disabled: this.disabled, placeholder: this.placeholder, value: this[VALUE_NAME] },
            on: {
              focus: this.onFocus,
              blur: this.onBlur,
              input: this.onInput,
              keydown: this.onKeydown,
              keyup: this.onKeyup
            }
          },
        ),
        h(
          'section',
          {
            class: `${NAME}__decrease`,
            on: { click: this.minus }
          },
          h(
            'i',
            { class: this.controlsPosition === 'right' ? `${ICON_NAME}-arrow-down` : `${ICON_NAME}-minus` }
          )
        ),
        h(
          'section',
          {
            class: `${NAME}__increase`,
            on: { click: this.plus }
          },
          h(
            'i',
            { class: this.controlsPosition === 'right' ? `${ICON_NAME}-arrow-up` : `${ICON_NAME}-plus` }
          )
        ),
        h(
          'label',
          {
            class: { [`${NAME}__text`]: true, 'is-active': !this.isFocus && this.label },
          },
          this.label
        )
      ]
    )
  }
})